Spring JDBC Batch Insert

개념

Batch Insert란?

많은 양의 데이터를 추가할때 고려해야하는 몇 가지 부분이 있다.

  1. 데이터베이스 서버 커넥션 수
  2. 추가하는 테이블의 칼럼 수
  3. 데이터베이스 리퀘스트 수

첫 번째는 connection pooling을 이용해 개선한다. 두 번째는 설계시 컬럼을 줄이는 방향으로 설계해야한다. 세 번째가 바로 Batch Insert를 사용하면 성능 개선을 할 수 있는 부분이다.

Batch Insert를 이용하면 애플리케이션이 데이터베이스에 연결을 설정하고 각 문을 하나씩 전송하는 대신 여러 SQL 문을 한 번에 실행할 수 있다. 따라서 네트워크 오버헤드를 크게 줄일 수 있다.

특히나 MSA 구조에서 DB 서버가 백엔드 서버와 분리되어있는 경우가 많은데, 이런 경우 데이터베이스에 접근하기 위해서는 네트워크를 거쳐서 왔다 갔다 해야하기 때문에 오버헤드가 크게 발생할 수 있을 것이다.

Batch Insert의 장점

1. 네트워크 왕복 횟수 감소:

  • 개별 삽입 문을 실행할 때 각 문은 데이터베이스 서버로 별도의 왕복이 필요하다. 이로 인해 지연 시간과 네트워크 오버헤드가 증가할 수 있다.
  • Batch Insert을 사용하면 한 번의 데이터베이스 왕복으로 여러 레코드가 삽입되므로 네트워크 통신에 소요되는 시간이 줄어든다.

2. 데이터베이스 성능 최적화:

  • 데이터베이스는 배치 작업을 보다 효율적으로 처리하도록 설계된 경우가 많다.
  • 일괄적으로 레코드를 삽입할 때 데이터베이스는 로깅을 줄이고 잠금 경합을 줄이며 리소스를 더 잘 사용하는 일괄 삽입 기술을 사용하여 작업을 최적화할 수 있다.

3. 트랜잭션 오버헤드 감소:

  • 개별 삽입 문을 사용할 때 각 문은 종종 자체 트랜잭션에서 실행된다. 이로 인해 트랜잭션 오버헤드가 증가하고 성능이 저하될 수 있다.
  • 일괄 삽입을 사용하면 모든 레코드가 단일 트랜잭션 내에 삽입되므로 트랜잭션 오버헤드가 줄어들고 성능이 향상된다.

4. 애플리케이션 성능 개선:

  • 일괄 삽입은 데이터베이스 통신 및 처리에 소요되는 시간을 줄여 애플리케이션의 전반적인 성능을 향상시킬 수 있다. 이를 통해 리소스를 확보하고 애플리케이션이 더 많은 수의 동시 사용자 또는 작업을 처리할 수 있다.

Spring JDBC Batch Insert

JDBC API에서 Batch 기능을 제공하지만, 실제 작동하는 드라이버가 그 기능을 구현했는지는 알 수 없다. 하지만 Spring이 확인해준다고 한다.

However, in most cases with the JdbcTemplate API, Spring already checks it for us and otherwise falls back to regular behavior. baeldung.com

사용법

jdbcTemplate.batchUpdate를 이용하면 된다. 다만, PreparedStatement로 동적 SQL 쿼리를 만들어두어야한다. 아니면, 아래처럼 동적 SQL 쿼리문의 place holder(?)에 맞추어 값을 준비해둬면 된다.

this.jdbcTemplate.execute("DROP TABLE customers IF EXISTS");  
this.jdbcTemplate.execute("CREATE TABLE customers(" +  
"id int AUTO_INCREMENT, first_name VARCHAR(255), last_name VARCHAR(255))");  
  
List<Object[]> splitUpNames = Arrays.asList("John Woo", "Jeff Dean", "Josh Bloch", "Josh Long").stream()  
.map(name -> name.split(" "))  
.collect(Collectors.toList());  
  
this.jdbcTemplate.batchUpdate("INSERT INTO customers(first_name, last_name) VALUES (?,?)", splitUpNames);

배치 사이즈는 주로 50-100 정도로 한다고 한다. 이유는 데이터베이스마다 정해진 네트워크 패키지 제한용량이 있기 때문이다.

Usually, the recommended batch size is 50-100, but it highly depends on our database server configurations and the size of each batch package. For example, MySQL Server has the configuration property called max_allowed_packet with a 64MB limit for each network package. While setting the batch size, we need to be careful not to exceed our database server limits. baeldung.com